package com.hifar.test.api.util;

import com.hifar.test.api.constant.AuthConstants;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * RSA加密工具类
 * 用于密码的RSA非对称加密和解密
 */
public class RSAUtil {
    
    /**
     * RSA算法
     */
    private static final String RSA_ALGORITHM = "RSA";
    
    /**
     * 字符编码
     */
    private static final String CHARSET = "UTF-8";
    
    /**
     * 使用默认公钥加密密码
     * 
     * @param password 原始密码
     * @return 加密后的密码（Base64编码）
     * @throws Exception 加密异常
     */
    public static String encryptPassword(String password) throws Exception {
        return encryptPassword(password, AuthConstants.RSA_PUBLIC_KEY);
    }
    
    /**
     * 使用指定公钥加密密码
     * 
     * @param password 原始密码
     * @param publicKeyStr 公钥字符串（Base64编码）
     * @return 加密后的密码（Base64编码）
     * @throws Exception 加密异常
     */
    public static String encryptPassword(String password, String publicKeyStr) throws Exception {
        // 将Base64编码的公钥字符串转换为PublicKey对象
        byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        
        // 创建Cipher对象并初始化
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        // 加密密码
        byte[] encryptedBytes = cipher.doFinal(password.getBytes(CHARSET));
        
        // 返回Base64编码的加密结果
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
    /**
     * 使用默认私钥解密密码
     * 
     * @param encryptedPassword 加密后的密码（Base64编码）
     * @return 解密后的原始密码
     * @throws Exception 解密异常
     */
    public static String decryptPassword(String encryptedPassword) throws Exception {
        return decryptPassword(encryptedPassword, AuthConstants.RSA_PRIVATE_KEY);
    }
    
    /**
     * 使用指定私钥解密密码
     * 
     * @param encryptedPassword 加密后的密码（Base64编码）
     * @param privateKeyStr 私钥字符串（Base64编码）
     * @return 解密后的原始密码
     * @throws Exception 解密异常
     */
    public static String decryptPassword(String encryptedPassword, String privateKeyStr) throws Exception {
        // 将Base64编码的私钥字符串转换为PrivateKey对象
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        
        // 创建Cipher对象并初始化
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        // 解密密码
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedPassword);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        
        // 返回解密结果
        return new String(decryptedBytes, CHARSET);
    }
    
    /**
     * 验证公钥格式是否正确
     * 
     * @param publicKeyStr 公钥字符串
     * @return 是否为有效的公钥
     */
    public static boolean isValidPublicKey(String publicKeyStr) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            keyFactory.generatePublic(keySpec);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 验证私钥格式是否正确
     * 
     * @param privateKeyStr 私钥字符串
     * @return 是否为有效的私钥
     */
    public static boolean isValidPrivateKey(String privateKeyStr) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            keyFactory.generatePrivate(keySpec);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
